import queue
from queue import Queue
from jsonpath import jsonpath
import execjs
import os
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
import re
import requests

class Mp3Music:

    music_list_queue = Queue()

    download_queue = Queue()

    ur1 = 'https://y.music.163.com/m/discover/toplist?id={}'

    url = 'https://music.163.com/weapi/song/enhance/player/url/v1'

    headers = {
        "User-Agent": 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36 Edg/127.0.0.0',
        "Referer": 'https://music.163.com/',
        "Cookie": 'MUSIC_R_T=1696512325339; MUSIC_A_T=1696512284475; NMTID=00OPWhNEEcZ2FhtKUqWhJNXu3W5aDoAAAGRwSFX9g; _ntes_nnid=c60aa392af262527f6948f1d686495c6,1725522074250; _ntes_nuid=c60aa392af262527f6948f1d686495c6; WEVNSM=1.0.0; WNMCID=yxmyhp.1725522076378.01.0; _ga=GA1.1.1299997273.1727544235; _clck=1upvska%7C2%7Cfpk%7C0%7C1732; _ga_PTGVM6PCHS=GS1.1.1727544235.1.1.1727544267.0.0.0; WM_NI=rHbLVsgtc7Wp8XwjcXBK0qHOswUXWB5a6Gw0Vzz5Gvg8NI%2B9sBej0W7HUsPajbihmKS1iIoPLHedYkUqWaxoifdUuarzVoK7lcMGAtVRnfAItJ2Gwky92AN%2Ft4MCNk%2FAcjE%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eeb8aa49f5acb9a7cd64bb9e8bb2d54b969e8eadc7548fa7fe93d063afa8a182bb2af0fea7c3b92ab298aeadd579a5acadd8d67cfc88b98be25482950092cb45b1a99bb9d64af7bffaa8f63c96a6b6d6c67ea5e882aaaa33b19eab8bb35df5989b94d36baabea789f04191efa7aaee5c9098ab85dc6197af9982fb65abbaacb6f86bb2a69a90ca3db0bd83a8c480968ea287c443b896fea8f661bbe7fea2cd25b8ec83a4cd61ed9fad8bc837e2a3; WM_TID=CVfaDB7y%2FuRAQVRBEAaHDZi3qZj3l5bs; sDeviceId=YD-Iyq29Y7psMRFB1QEVRKGWNjm7I2zn2hX; ntes_utid=tid._.gUSPSlxvFrFFQhVFABaXScjj%252FJ2ikq9m._.0; __snaker__id=XU7xcGBnXouVfzTW; gdxidpyhxdE=ePaAM5Hb%2B57B7ff6J1Qc8mJQ5jvCKd6P076Hl2i5A1lfrC9LjuHpXv%2B3T0IEVYYp1JoCtqPxbGd6dhjznob0X%2Bc3AqI39%5CU4llvRnxKvZMDGG3qr7UtWgRIqqU078vxe%2BsbndDR0LT1u7wf4aI%2FGQEl6SjciyIghL%2FOdxzruSLZZzrrY%3A1729495874694; __csrf=4e74cf1990c3d21f2dfb6e8e7211116d; MUSIC_U=00B7A8278CCA370FB1D997A09444F6F5795C7011259FD775641B2789E07DE1B49FD4B40084801E341CF1EFF455D6902AE107F35A3239B70AD80A47DCFFC4D4706FD72C3D221089FC1A5608B8373B5515FFFF60883DC2E7A1BAB47973055ED74C522D65C26298B3A11121906B4E5F5FDC9AFC46629F1980149BEF467173D63111A7E799DD184422EBE7428E499EC819BD5767E7B0C7CFC76E617FA4E276DE92822C5C1937ABB5357798CC929B2DF1503F5CC3B91418284DB116C52C838DF1ABD0C0B8EAD2ACF527E22D8C570CD808F35F1A99CAF9D4EB7B517B9F781454EA09DA2FAB410EFAF3B2BDC8F5E2317B5E46C810F259C21DA60D782202C867E2395952446B77551A5DB1F0CFBF6762BD3F9B46084E8E05496434A1359EEE96551D7239510A89F228AA8C557C34662302F2E198DBDBC7CB818A95D1DA7CF8F0B3E6B5F086DF8347C9591F351B35EB3CC795E31F2DC915783B0BDD8477F9525CABBC7E16EE; __remember_me=true; ntes_kaola_ad=1; _iuqxldmzr_=32; playerid=98788885; JSESSIONID-WYYY=G0OZGrwhgri3ae0vlFr08oZwD%2BSG8IQG02CEgdvplDKWieH4Tf%2Bzfm1p8uwXjhoZo1lXn7yhejT9CT2crwOziSuA63mzJFDU%2BRMIHSow4K8tjgoTxyeFIZZ%2BcO5jBxP28oY%5ClTlFUVvVuATF6WOParCR%2BbpDG4FnTanXcxA2zkHj6jCf%3A1729500681746',
    }

    js_file = open('wang.js', 'r', encoding='utf-8')
    js_code = execjs.compile(js_file.read())

    def get_music_list(self,charts_id):

        ur1 = self.ur1.format(charts_id)
        response = requests.get(url=ur1, headers=self.headers)
        result1 = response.content.decode()
        html = etree.HTML(result1)
        names = html.xpath('//div[@class="m-sglst"]//div[@class="f-thide sgtl"]/text()')
        music_url = html.xpath('//div[@class="m-sglst"]/a[@class="m-sgitem"]/@href')
        file_name = html.xpath('//div[@class="plhead_fr"]/h2/text()')[0]
        music_path = 'D:\\歌曲\\{}'.format(file_name)
        new_list = list(zip(names, music_url))
        if not os.path.isdir(music_path):
            os.makedirs(music_path)

        self.music_list_queue.put((music_path,new_list))

    def paser_data(self):

        while True:
            try:
                music_path, new_list = self.music_list_queue.get(timeout=3)
            except queue.Empty:
                break

            for item in new_list:
                song_id = re.findall(r'id=(.+)&', item[1])
                a = {"ids": song_id, "level": 'standard', "encodeType": 'aac',
                     "csrf_token": '4e74cf1990c3d21f2dfb6e8e7211116d'}
                result = self.js_code.call('getData', a)
                data = {
                    "params": result['encText'],
                    "encSecKey": result['encSecKey']
                }
                musc = requests.post(url=self.url, data=data, headers=self.headers)
                music_url = jsonpath(musc.json()['data'], '$..url')[0]
                self.download_queue.put((music_path,music_url,item[0]))


    def save_data(self):

        while True:
            try:
                music_path, music_url,music_name= self.download_queue.get(timeout=3)
            except queue.Empty:
                break
            response = requests.get(url=music_url, headers=self.headers)
            with open('{}\\{}.mp3'.format(music_path, music_name), 'wb') as f:
                f.write(response.content)
                print(music_name,"下载完成")

if __name__ == '__main__':

    mp3 = Mp3Music()

    charts_id = input("请输入榜单id(例如3779629): ")
    # 实现多线程下载歌曲
    with ThreadPoolExecutor(max_workers=5) as t:

        t.submit(mp3.get_music_list,charts_id)

        t.submit(mp3.paser_data)
        # 2个下载歌曲
        t.submit(mp3.save_data)
        t.submit(mp3.save_data)

    print("下载完成")
